# 客户端将请求发送给服务器，服务器把请求发送给正在运行的flask web 程序实例
# flask的应用实例需要知道需要运行那些代码来处理请求
# 因此就需要将请求和Python的代码形成映射关系，完成这一映射关系的就是路由
# 具体来说，请求是和url绑定的，前缀是文件，后面用%&等连接，因此实际上请求不止访问网页
# 还会包括提交表单、点击播放等等都是请求，都是由url唯一标识
# 因此使用router来解决所有的映射，实现了为特定的请求运行特定的代码来处理

import sys
from flask import Flask
from pathlib import Path

if __name__ == "__main__":
    sys.path.append(
        Path(__file__).absolute().parent.parent.__str__()
    )

from base_frame import Application

@Application.app.route("/")
def welcome():
    return "<h1 align=\"center\">Welcome to my raspberry Pi!</h1>"

@Application.app.route("/hello")
def hello():
    return "Hello, you've visit /hello"

@Application.app.route("/hi")
def hi():
    return "<h1 align=\"center\">hi hi</h1>"


# methods 指定了该路由能够接受什么样的请求
@Application.app.route("/say", methods=["GET", "POST"])
def say():
    return "<h1 align=\"center\">You cannot do any requirements except GET and POST</h1>"

@Application.app.route("/postonly", methods=["POST"])
def post_only():
    return "<h1>you will never see this</h1>"

# 指定端点以实现url的关联
@Application.app.route("/endpoint", methods=["GET"], endpoint="hello1")
def none_invoked():
    return "<h1>you will somehow see this</h1>"


# 利用尖括号进行正则匹配，以实现url中的匹配，相当于从url中获取值，但是默认获得的是字符串
@Application.app.route("/user/<id>")
def match_patter(id: str):
    id = int(id)
    if id == 1:
        return f"you've typed id={id}, PYTHON!"
    elif id == 2:
        return f"you've typed id={id}, C++!"
    elif id == 3:
        return f"you've typed id={id}, JAVA!"
    else:
        return f"you typed nothing"


# 使用类型转换器来获得指定类型的值，冒号后面不能加空格
# 具体的还有 string（不包含斜杠）、float（正浮点数）、int（正整数）、path（接受包含斜杠的文本）
@Application.app.route("/<int:id>")
def match_with_changer(id: int):
    if id == 1:
        return f"you've typed id={id}, PYTHON!"
    elif id == 2:
        return f"you've typed id={id}, C++!"
    elif id == 3:
        return f"you've typed id={id}, JAVA!"
    else:
        return f"you typed nothing"


# 自定义转换器，需要利用werkzeug中定义的的转换器的父类来写自己的转换器
# 本质上路由的匹配是正则表达式的匹配，因此我们继承父类之后重写自己的正则表达式即可
from werkzeug.routing import BaseConverter

class MyRegexConverter(BaseConverter):
    def __init__(self, url_map, regex) -> None:
        print(f"url_map = {url_map}")
        super(MyRegexConverter, self).__init__(url_map)

        self.regex  = regex
    
    def to_python(self, value: str):
        print(f"called parent to_python value={value}")
        return value

# 写完之后要添加到转换器列表中去
Application.app.url_map.converters["re"] = MyRegexConverter

# 正则表达式在这里重写
@Application.app.route("/r/<re('123\d+'):id>")
def use_my_converter(id):
    return f"{id}"


if __name__ == "__main__":
    app = Application()

    app.start_app()


